/**
 * @class   wosh::services::MediaDirectorBundle
 * @brief   Network-singleton service designed to manage whole-house entertainment and multimedia.
 *
 *
 * Assuming there are PlayerAudio/PlayerVideo available.
 *
 *
 * - MediaDirector is a CommunicatorService, supporting audio/(video?)
 *   Selects the best (if any) Player to deliver (audio/video) Notifications.
 *   Flow:
 *    - get current User location
 *    - if ( user isn't at home || distance(user, nearest mediazone) > MAX )
 *      reply error
 *    - (pause the mediazone) deliver notification (restore scenario)
 *
 *
 * ---------------------------------------------------------------
 * ---------------------------------------------------------------
 *
 * - PARSER: built (and keep updated) MediaZone (information)
 * - WORKER: ??
 *
 *
 * ---------------------------------------------------------------
 * ---------------------------------------------------------------
 * - assists inhabitans and take care of home
 *
 *  - turn on/off lights on movement-detection
 *  - turn on/off music on movement-detection
 *
 * SPECIFICATION Proposal 0.51
 * \verbatim


_____________________________________________________________________
DATABASE:
 - DB HISTORY


CREATE TABLE `wosh`.`MediaDirector_MediaDB` (
`id` BIGINT NOT NULL ,
`Ts` TIMESTAMP NOT NULL ,
`Track` VARCHAR( 512 ) NOT NULL ,
`Player` VARCHAR( 255 ) NULL ,
`Location` VARCHAR( 512 ) NULL ,
`User` VARCHAR( 64 ) NULL ,
PRIMARY KEY ( `id` )
) ENGINE = MYISAM 


 - DB MUSIC
   - riga = 1 track
   - { track,artist,album,genre, keywords }

=> Effetti
   - remember last scenario [per user/location/song] (ex. when back to home)
   - move music within rooms [using smart-last-scenario selection]
   - FUTURE: prevision next, autogenerate playlist
_____________________________________________________________________
=====================================================================

Mapping con EVENTS (as SWITCH)

 - N swtich/dimmer (located somewhere in a room with at least 1 audiobox => IDENTIFIED as an AUDIO-LOCATION [ZONE] )

   - PLAY/STOP KEY
      - ON(1)  :
        - when CURRENT location is NOT PLAYING do :
          - if ANOTHER location is PLAYING do SYNCH
          - if zones are OFF do RESTORE last music scenario
        - when CURRENT location is PLAYING do
          - switch source of case ON(1).1.1
          - switch scenario case ON(1).1.2
      - ON(2)  :													[NOT IMPLEMENTED]
        - when CURRENT location is PLAYING do						????????
          - if ANOTHER location is PLAYING do MOVE
          - if zones are OFF do RESTORE last music scenario
      - OFF(1) :
        - when PLAYING do STOP
      - OFF(2) :													[NOT IMPLEMENTED]
        - when PLAYING do STOP OTHERS
      - BRIGHT :											???????? [NOT IMPLEMENTED]
      - DIM    :											???????? [NOT IMPLEMENTED]

   - TRACK KEY
      - ON(1)  : prev
      - ON(2)  : first												[NOT IMPLEMENTED]
      - OFF(1) : next
      - OFF(2) : last												[NOT IMPLEMENTED]
      - BRIGHT : seek position [each event is 'position +']
      - DIM    : seek position [each event is 'position -']

   - VOLUME KEY
      - ON(1)  : UN-mute
      - ON(2)  : UN-mute and RESTORE default volume					[NOT IMPLEMENTED]
      - OFF    : mute
      - BRIGHT : higher volume [each event is 'volume +']
      - DIM    : lower volume [each event is 'volume -']


DOUBLE-EVENT Support
 - wait 5 sec before applying

EACH EVENT IS MAPPED TO ZONE?
 - map<event, command>

COMMON Functions:
 - moveTo(from_zone, to_zone)
 - restore(to_zone)
 - restore(from_zone, to_zone)

_____________________________________________________________________

\endverbatim
 *
 *
 * ---------------------------------------------------------------
 * MediaDirector is a CommunicatorService, supporting audio/(video?)
 * Assuming there are PlayerAudio/PlayerVideo available.
 *
 * ??  selects the best (if any) Player to play (audio/video) Notifications.
 *
 *
 *
 *
 *
 *
 *
 * @ingroup Services
 ****************************************************************************
 * @version $Id: MediaDirectorBundle.h 2887 2010-08-11 08:09:41Z alex $
 * @author  Alessandro Polo
 ****************************************************************************/
/* Copyright (c) 2007-2010, WOSH - Wide Open Smart Home 
 * by Alessandro Polo - OpenSmartHome.com
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the OpenSmartHome.com WOSH nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY Alessandro Polo ''AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL Alessandro Polo BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ****************************************************************************/

#ifndef __WOSH_Bundles_Services_MediaDirector_H__
 #define __WOSH_Bundles_Services_MediaDirector_H__

 #include <core/BundleGeneric.h>
 #include <core/Thread.h>

 #include <core/Communicator.h>
 #include <interfaces/Service.h>
 #include <interfaces/services/MediaDirector.h>
 #include <interfaces/services/CommunicatorService.h>

 #include "IMediaDirectorListener.h"


namespace wosh {
 namespace services {

 #define _MediaDirector_VERSION			"0.6"


class MediaDirectorBundle :	public BundleGeneric,
							public virtual wosh::interfaces::services::CommunicatorService,
							public virtual wosh::interfaces::services::MediaDirector,
							public virtual IMediaDirectorListener
 {
	WOSH_BUNDLE(wosh::services::MediaDirectorBundle)
	WOSH_BUNDLE_INTERFACE("wosh::services::MediaDirector")
	WOSH_BUNDLE_SINGLETON(1,0)


	public:
		MediaDirectorBundle();

		virtual ~MediaDirectorBundle();


	public:
		WRESULT bundleStart();
		WRESULT bundleStop();

		void busMessage( const Message& message, const Bus* source );


/** @name MediaDirector Interface
 * @{
 ******************************************************************************/
	public:
		WRESULT loadMediaZones();
		WRESULT saveMediaZones();

		WRESULT loadMediaLists();
		WRESULT saveMediaLists();

//@}
/** @name Getters
 * @{
 ******************************************************************************/
	public:

/** @name CommunicatorService Interface
 * @{
 ******************************************************************************/
	public:
		bool isUserReachable( const string& wosh_username );
		WRESULT sendMessageToUser( const string& wosh_username, const string& message );
		WRESULT sendMessageTo( const string& custom_username, const string& message );
		WRESULT notify( const Notification* notification );

//@}
/** @name CommunicationManager Interface for Communication callbacks
 * @{
 ******************************************************************************/
	public:
		void updateLocations( const vector<string>& locations );

		WRESULT load_MediaTrack( MediaZone* zone, vector<MediaTrack*>& tracks, MediaDirectorImpl* source );
		WRESULT save_MediaTrack( MediaTrack* track, MediaDirectorImpl* source );

//@}
/** @name Internal methods
 * @{
 ******************************************************************************/
	protected:
		WRESULT updateZones();

		void busMessageForZone_( MediaZone* zone, const Message& message, const Bus* source );
		void busMessageForMediaList_( MediaList* mList, const Message& message, const Bus* source );
//@}
	private:
		Response* mmDoListPlayList( const Request* request);
		Response* mmDoGetMatrix( const Request* request );

		Response* mmDoGetPlayList( const Request* request );

		Response* mmDoListJoin( const Message* requestMessage );
		Response* mmDoSendMessageToUser( const Message* requestMessage );
		Response* mmDoPlay( const Message* requestMessage );

	protected:
		BusConnector BusBuilding;
		BusConnector BusDevices;

		MediaDirectorImpl* mediaWorker;
		MediaDirectorParser* zoneParser;

		URI PlaylistVirtualURI;
		URI ZoneVirtualURI;


}; // class def

 }; // namespace services
}; // namespace wosh

#endif //__WOSH_Bundles_Services_MediaDirector_H__
